//
//  LTStethoscopeSDK.h
//  hc21SDK
//
//  Created by lanzhongping on 2021/1/6.
//

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import "SleepStagingResultV2.h"
#import "SRDeviceInfo.h"
#import "SDKConstant.h"
#import "SrEcgData.h"
#import "EcgParamObj.h"
#import "SrEcgAlgorithmResults.h"
NS_ASSUME_NONNULL_BEGIN

@class SRBLeService;
@class SRHistoryData;
@class SRHistoryDataSR03;


typedef enum {
    // Value zero must not be used !! Notifications are sent when status changes.
    SROTAR_SRV_STARTED      = 0x01,     // Valid memory device has been configured by initiator. No sleep state while in this mode
    SROTAR_CMP_OK           = 0x02,     // SPOTA process completed successfully.
    SROTAR_SRV_EXIT         = 0x03,     // Forced exit of SROTAR service.
    SROTAR_CRC_ERR          = 0x04,     // Overall Patch Data CRC failed
    SROTAR_PATCH_LEN_ERR    = 0x05,     // Received patch Length not equal to PATCH_LEN characteristic value
    SROTAR_EXT_MEM_WRITE_ERR= 0x06,     // External Mem Error (Writing to external device failed)
    SROTAR_INT_MEM_ERR      = 0x07,     // Internal Mem Error (not enough space for Patch)
    SROTAR_INVAL_MEM_TYPE   = 0x08,     // Invalid memory device
    SROTAR_APP_ERROR        = 0x09,     // Application error
    
    // SUOTAR application specific error codes
    SROTAR_IMG_STARTED      = 0x10,     // SPOTA started for downloading image (SUOTA application)
    SROTAR_INVAL_IMG_BANK   = 0x11,     // Invalid image bank
    SROTAR_INVAL_IMG_HDR    = 0x12,     // Invalid image header
    SROTAR_INVAL_IMG_SIZE   = 0x13,     // Invalid image size
    SROTAR_INVAL_PRODUCT_HDR= 0x14,     // Invalid product header
    SROTAR_SAME_IMG_ERR     = 0x15,     // Same Image Error
    SROTAR_EXT_MEM_READ_ERR = 0x16,     // Failed to read from external memory device
    
} SROTA_STATUS_VALUES;


typedef NS_ENUM(UInt8, EXCUTED_CMD) {
    EXCUTED_CMD_SET_SPORT_MODE = 0x01,         //运动模式设置
    EXCUTED_CMD_SET_HR_TEMP_MEASURE = 0x02,    // 体温 心率设置
    EXCUTED_CMD_SET_OXYGEN_MEASURE = 0x03,     //血氧测量设置
    EXCUTED_CMD_SYNC_TIME = 0x04,              // 时间同步
    EXCUTED_CMD_GET_OXYGEN_HRV = 0x05,         // 获取心率血氧
    EXCUTED_CMD_GET_STEPS = 0x06,              //获取计步
    EXCUTED_CMD_GET_TEMPERATURE = 0x07,        //获取体温
    EXCUTED_CMD_SHUT_DOWN = 0X08,              // 关机
    EXCUTED_CMD_REBOOT = 0X09,                 // 重启
  
    EXCUTED_CMD_FACTORY_RESET = 0x0a,          // 恢复出厂设置
    
    EXCUTED_CMD_HIS_COUNT = 0x0c,              // 历史数据个数
    EXCUTED_CMD_HIS_DATA = 0x0d,               // 历史数据
    EXCUTED_CMD_CLEAR_HIS_DATA = 0x0e,         // 清空历史
    EXCUTED_CMD_DEVICE_INFO = 0x0f,            // 设备信息
    EXCUTED_CMD_SN = 0x10,                     // sn
    EXCUTED_CMD_BATTERY = 0X11,                // 电池电量
    EXCUTED_CMD_BIND = 0X15,                   // 绑定解绑设备
    EXCUTED_CMD_START_MANUFACT_CER = 0x1B,     // 开始厂家验证
    EXCUTED_CMD_MANUFACT_SEND_R2 = 0x1C,       // 向设备发送解密原文
    EXCUTED_CMD_SPORT_MODE = 0x20,             // 运动模式

    EXCUTED_CMD_FUNCTIN_SWITCH = 0x31,         // 设备功能开关
    EXCUTED_CMD_FUNCTIN_SET_HR_MEASURE_DURATION = 0x3C, // 设置测量时长
    EXCUTED_CMD_FUNCTIN_GET_DEVICEINFO_5 = 0x3d, // 获取设备信息5 心率测量时长 回包0x8f
};// 下发命令字



typedef NS_ENUM(NSUInteger, REALTIME_STATUS) {
    REALTIME_STATUS_NO_MEASURE = 0x00,
    REALTIME_STATUS_MEASURING = 0x01,
    REALTIME_STATUS_DATA_USEFUL = 0x02,
};

typedef NS_ENUM(NSUInteger, REALTIME_MEASURE_TYPE) {
    REALTIME_MEASURE_HR =  0X00,
    REALTIME_MEASURE_SPO = 0X01,
};


typedef NS_ENUM(uint8_t, SOS_DOUBLESLAP_INTERVAL_TYPE) {
    INTEVAL_50MS =  0x00,   // 50ms
    INTEVAL_100MS = 0x01,   //100ms
    INTEVAL_150MS = 0x2,    //150ms
    INTEVAL_200MS = 0x3,    //200ms
    INTEVAL_250MS = 0x4,    //250ms
    INTEVAL_375MS = 0x5,    //375ms
    INTEVAL_500MS = 0x6,    //500ms
    INTEVAL_700MS = 0x7,    //700ms
    
};

typedef NS_ENUM(NSInteger, FUNCTION_ERROR) {
    FUNCTION_ERR_NONE = 0,              // No errors
    FUNCTION_ERR_BLE_NOT_CONNECT,       // Bluetooth not connected
    FUNCTION_ERR_BLE_NOTREADY_READWRITE,// Ring is not ready for reading and writing
    FUNCTION_ERR_OEMAUTH_NOTFINISH,        // OEM certification is not completed
};

typedef NS_ENUM(uint8_t, SR_UPD_ERROR) {
    UPGRADE_ERROR_FORCE_EXIT_OF_UPGRADE_SERVICE = 0x03, //Forced exit of SPOTA service.
    UPGRADE_ERROR_PATH_DATA_CRC_MISMATCH = 0x04, //Patch Data CRC mismatch.
    UPGRADE_ERROR_PATH_LENGTH_MISMATCH = 0x05 ,//Received patch Length not equal to PATCH_LEN characteristic value.
    UPGRADE_ERROR_EXTERNAL_MEMORY_ERROR = 0x06, //External Memory Error. Writing to external device failed.
    UPGRADE_ERROR_INTERNAL_MEMORY_ERROR = 0x07 ,//Internal Memory Error. Not enough internal memory space for patch.
    UPGRADE_ERROR_INVALID_MEMORY_DEVICE = 0x08 ,//Invalid memory device.
    UPGRADE_ERROR_APPLICATION_ERROR = 0x09 ,//Application error.
    UPGRADE_ERROR_INVALID_IMAGE_BANK = 0x11 ,//Invalid image bank.
    UPGRADE_ERROR_INVALID_IMAGE_HEADER = 0x12 ,//Invalid image header.
    UPGRADE_ERROR_INVALID_IMAGE_SIZE = 0x13 ,//Invalid image size.
    UPGRADE_ERROR_INVALID_PRODUCT_HEADER = 0x14 ,//Invalid product header.
    UPGRADE_ERROR_SAME_IMAGE = 0x15 ,//Same Image Error.
    UPGRADE_ERROR_READ_EXTERNAL_MEMORY_DEVICE_FAILED = 0x16 ,//"Failed to read from external memory device."
    
};

/* about ble device scan and connect */
@protocol SRBleScanProtocal <NSObject>

@optional

/// scan device list fresh
/// @param perphelArray  scaned devices
-(void)srScanDeviceDidRefresh:(NSArray<SRBLeService *> *)perphelArray;


/// phone ble power state change
/// @param isOn  YES = powerOn NO = pwoerNO
- (void)srBlePowerStateChange:(CBManagerState)state;


- (void)srBleDidConnectPeripheral:(SRBLeService*)service;
- (void)srBleDidDisconnectPeripheral:(SRBLeService*)service;



@end

/* about ble data translate */
@protocol SRBleDataProtocal <NSObject>




/// perphel is ready for read write
/// @param service current connect devices
- (void)srBleDeviceDidReadyForReadAndWrite:(SRBLeService*)service;



/// call back value of hrv
/// @param hrv hrv
//- (void)srBleRealtimeHRV:(NSNumber *)hrv BloodOxygen:(NSNumber *)bloodOxygen HeartRate:(NSNumber *)hr Status:(REALTIME_STATUS)status;


/// Call back for realtime spo2 measurement
/// @param spo -- spo2
- (void)srBleRealtimeSpo:(NSNumber *)spo;


/// Call back for realtime heart rate measurement
/// @param hr  -- heart rate
- (void)srBleRealtimeHeartRate:(NSNumber *)hr;


/// Call back for realtime HRV measurement
/// @param hrv  -- HRV
- (void)srBleRealtimeHrv:(NSNumber *)hrv;


/// call back device's battery level and charging state
/// @param batteryLevel battery level
/// @param isCharging YES = device is charging
- (void)srBleDeviceBatteryLevel:(NSUInteger)batteryLevel IsCharging:(BOOL)isCharging;


/// call back value of device's sn code
/// @param sn sn code
- (void)srBleSN:(NSString *)sn;

- (void)srBleDeviceInfo:(SRDeviceInfo *)devInfo;



- (void)srBleHistorySr03DataWithCurrentCount:(NSInteger)currentCount IsComplete:(BOOL)isComplete DEPRECATED_MSG_ATTRIBUTE("deprecate from V1.0.7, use srBleCmdExcute:Succ:Reason: instead");


/// call back realtime steps
/// @param steps steps
- (void)srBleDeviceRealtimeSteps:(NSNumber *)steps DEPRECATED_MSG_ATTRIBUTE("deprecate from V1.1.1");


/// call back realtime skin temperature
/// @param temperature skin temperature Unit(℃)
- (void)srBleDeviceRealtimeTemperature:(NSNumber *)temperature;


/// call back for excute result of sended command
/// @param cmd  sended cmd
/// @param isSucc YES = success
- (void)srBleCmdExcute:(EXCUTED_CMD)cmd Succ:(BOOL)isSucc DEPRECATED_MSG_ATTRIBUTE("deprecate from V1.0.7, use srBleCmdExcute:Succ:Reason: instead");

/// call back for excute result of sended command
/// @param cmd  sended cmd
/// @param isSucc YES = success
- (void)srBleCmdExcute:(EXCUTED_CMD)cmd Succ:(BOOL)isSucc Reason:(CMD_EXECTE_ERROR_REASON)reason;

/// 返回历史数据条目
/// @param count 历史数据数量
- (void)srBleHistoryDataCount:(NSInteger)count  DEPRECATED_MSG_ATTRIBUTE("deprecate from V1.0.7, use srBleHistoryDataProgress:IsComplete: instead");


/// Historical data synchronization progress
/// @param percent range (0.0 - 1.0)
/// @param isComplete YES = complete
- (void)srBleHistoryDataProgress:(float)percent IsComplete:(BOOL)isComplete;


/// gain device's cache data time out
- (void)srBleHistoryDataTimeout;

- (void)srBleIsbinded:(BOOL)isBinded;


/// Call back for OEM auth result
/// - Parameter authSucceddful: YES = auth successfully NO = please check company name.
-(void)srBleOEMAuthResult:(BOOL)authSucceddful;

/// Exception callback when issuing Bluetooth commands
/// - Parameter error:error code
-(void)srBleFunctionErrorCallBack:(FUNCTION_ERROR)error MehthodName:(NSString *)methodNm;


@optional
- (void)srBleHistorySr03Data:(SRHistoryDataSR03 *)hisData IsComplete:(BOOL)isComplete;

/// Notify that the sleep calculation is complete
- (void)calculatSleepFinish;


/// call back to report device's measure duration
/// - Parameter seconds: measuration druration
-(void)srBleMeasureDuration:(NSInteger)seconds;


/// Report real-time measurement infrared data
/// - Parameter irData: infrared data
-(void)srBleIrData:(uint16_t)irData;

/// Report real-time measured red light data
/// - Parameter redData: red light data
-(void)srBleRedData:(uint16_t)redData;


/// Report the blood oxygen measurement interval value and whether blood oxygen measurement is turned on
/// - Parameters:
///   - minuteInterval: Blood oxygen measurement interval (unit: minutes)
///   - on: YES = Blood oxygen measurement is on.
-(void)srBleOxygenMeasureInterval:(uint16_t)minuteInterval OxygenSwitch:(BOOL)on;


/// Callback ecg waveform data
/// - Parameters ecgObj: ecg waveform data object
-(void)srBleEcgWave:(SrEcgData *)ecgObj;

// ecg+ ppg混合
-(void)srBleEcgAndPPgWave:(SrEcgData *)ecgPpgObj;

// 回调计步阈值
-(void)srBleStepCountThreshold:(uint8_t)threshold;

/// ecg algorithm results
/// - Parameter ecgResult: algorithm results
-(void)srBleEcgAlgorithmResult:(SrEcgAlgorithmResults *)ecgResult;


/// Detect whether the finger is completely in contact with the ring
/// - Parameter leadOn: yes = full contact
-(void)srBleEcgEcgLeadOn:(BOOL)leadOn;

@end


@protocol SROTAProtocal <NSObject>


/// 错误回调
/// @param errorCode 错误码
-(void)srOtaError:(SR_UPD_ERROR)errorCode;
-(void)srOtaFinish:(BOOL)isSuccessful;
-(void)srOtaUpdateProgress:(float)progress;

@end



@interface LTSRingSDK : NSObject

@property(weak, nonatomic)id<SRBleScanProtocal> blescanDelegate;
@property(weak, nonatomic)id<SRBleDataProtocal> bleDataDelegate;
@property(weak, nonatomic)id<SROTAProtocal> bleOtaDelegate;  // ota 代理回调对象

@property(assign, nonatomic) BOOL debugCollect;// If it is YES, the SDK will also collect all historical data, regardless of whether it is worn or not. Used for debugging

+(instancetype)instance;


/// register and initialize sdk
/// - Parameter cp: company name . defalt is Linktop
-(void)registWithCompany:(NSString  * _Nullable )cp;

/// Set the SDK's lower filter limit for heart rate data.If this interface is not called, the default lower limit is 50.You only need to call this method once after calling registWithCompany to take effect. Available since 1.2.0
/// - Parameter hrLimitLow: Lower limit value range [0-200]
-(void)setHeartrateFilterLowerLimit:(NSUInteger)hrLimitLow;

// Get the SDK's lower filter limit for heart rate data. Available since 1.2.0
-(NSUInteger)heartrateFilterLowerLimit;


// iOS ble state
- (CBManagerState)bleCenterManagerState;

-(void)startBleScan;
-(void)stopBleScan;
-(void)connectDevice:(SRBLeService *)device;
-(void)disconnectCurrentService;

// 当前已连接的设备
-(SRBLeService *)currentDevice;


-(NSString *)functionGetSdkVersion;

/// send cmd to get oxygen and hrv data
/// @param isStart   NO=off   yes=on
-(void)functionOxygenOrHeartRate:(REALTIME_MEASURE_TYPE)type IsOpen:(BOOL)isStart;


/// send cmd to power off device
-(void)functionShutDownDevice;


/// send cmd to reboot device
-(void)functionRebootDevice;

/// get device's battery
-(void)functionGetDeviceBattery;


/// get steps
-(void)functionGetStepsOnce DEPRECATED_MSG_ATTRIBUTE("deprecate from V1.1.1");


/// get skin temperature
-(void)functionGetTemperatureOnce;


/// device reset to factory status
-(void)functionDeviceReset;


/// get device's SN code
-(void)functionGetDeviceSN;
/// get device's infomation
-(void)functionGetDeviceInfo;


/// Set the original waveform reporting switch in real-time measurement
/// @param isON YES = ON
-(void)functionSetRealmeasureWaveSwitch:(BOOL)isON;

/// blood oxygen measuring setting
/// @param startHor start hour, range in [0 23]
/// @param startMin start minute, range in [0 59]
/// @param startSecond start second, range in [0 59]
/// @param endHor end hour, range in [0 23]
/// @param endMin end minute, range in [0 59]
/// @param endSec end second, range in [0 59]
/// @param interval uint:minute,range in [5, 120]
/// @param isOn switch YES = turn on
-(BOOL)functionSettingOxygenMeasure:(NSUInteger)startHor StartMin:(NSUInteger)startMin StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec Interval:(NSUInteger)interval IsOn:(BOOL)isOn;



/// setting heart rate measure interval and skin temperature measure interval
/// @param hrInterval heart rate interval
/// @param skinTemperatureInterval skin temperature measure interval
/// @param isOn YES = turn on
-(void)functionSettingHeartRateMeasurInterval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval IsOn:(BOOL)isOn;


///
/// @param startHor <#startHor description#>
/// @param startMin <#startMin description#>
/// @param startSecond <#startSecond description#>
/// @param endHor <#endHor description#>
/// @param endMin <#endMin description#>
/// @param endSec <#endSec description#>
/// @param hrInterval <#hrInterval description#>
/// @param skinTemperatureInterval <#skinTemperatureInterval description#>
/// @param oxygeninterval <#oxygeninterval description#>
/// @param isOn <#isOn description#>
-(void)functionSettingSportMode:(NSUInteger)startHor StartMin:(NSUInteger)startMin
                       StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor
                         EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec
                     HrIntreval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval
                       BloodOxygenInterval:(NSUInteger)oxygeninterval
                           IsOn:(BOOL)isOn;

/// get device's cache history data
/// retrun YES = cmd send successful  retrun NO = the last history data process is translating
-(BOOL)functionGetHistoryData;


/// clear device's history data cache
-(void)functionClearDeviceHistoryCache;


///
/// @param bind YES = bind device NO = unbine device
-(void)functionSetBindeDevice:(BOOL)bind;


/// SOS setting
/// @param doubleTapTimes range in [1, 10]
/// @param singleTapInterval see SOS_DOUBLESLAP_INTERVAL_TYPE
/// @param tapDetectionThreshold range in [0, 63]
/// @param doubleTapEffectStartTime range in [0 - 100], unit:ms
/// @param doubleTapEffectEndTime range in [0 - 100], unit:ms  doubleTapEffectEndTime must latger than doubleTapEffectStartTime
/// @param sosOpen  sos switch
-(void)functionSetSosDoubleTapTimes:(uint8_t)doubleTapTimes
                  SingleTapInterval:(SOS_DOUBLESLAP_INTERVAL_TYPE)singleTapInterval TapDetectionThreshold:(uint8_t)tapDetectionThreshold
           DoubleTapEffectStartTime:(uint8_t)doubleTapEffectStartTime
             DoubleTapEffectEndTime:(uint8_t)doubleTapEffectEndTime
                               Open:(BOOL)sosOpen;

-(NSString *)macAddressFromBleAvdData:(NSDictionary *)advertisementData;


/**  About OTA **/

-(void)functionStartOta:(NSURL *)fileUrl;


/**  About OTA **/

-(void)functionGetDeviceMeasureDuration;
-(void)functionSetDeviceMeasureDuration:(NSInteger)duration;


-(void)setCurrentPeripheralService:(SRBLeService* _Nullable)peripheralService;

/* sprot mode */
/// Turn on sport mode
/// @param durationMinutes Duration Unit: Minute Range (5min - 180min)
/// @param valueInterval Device value interval, unit - second
-(void)functionStartSportMode:(uint16_t)durationMinutes ValueInterval:(uint16_t)valueInterval WorkType:(WORKOUT_TYPE)wkType;

/// Turn off sport mode manually
-(void)functionShutdownSportMode;



//-(void)cleanAccount;



//-(void)sdkQuerySleepFrom:(NSDate *)beginDate To:(NSDate *)endDate DeviceMacaddrss:(NSString *)masAddress Complete:(void(^)(void))cpmplete;



/// calculate average br druraing sleep
/// - Parameter sleepStageData: sleep data
-(NSNumber *)calcBreathRateDuraingSleep:(StagingDataV2 *)sleepStageData;

/// ecg measurement on and off
/// - Parameter on: YES= Turn on , NO = Turn off
///
-(BOOL)functionECGMeasure:(BOOL)on Param:(EcgParamObj * _Nullable)paramObj DispSrc:(BOOL)isFilterWave;

/// ecg和ppg同时测量
/// - Parameter on: YES 开 NO 关
-(void)functionEcgAndPpgMeasure:(BOOL)on;

-(EcgParamObj *)ecgParamObj;

/// 设置计步阈值
/// - Parameter threshold:  计步阈值范围为：0x0-0x3F
-(void)functionSetStepCountingThreshold:(uint8_t)threshold;




- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;

@end

NS_ASSUME_NONNULL_END
